<!DOCTYPE html>
<html>

<head>
    <title>图层遮罩</title>
    <link rel="stylesheet" href="./css/ol.css" type="text/css" />
    <script src="./js/ol.js"></script>
</head>
<style></style>

<body>

<div id="map" class="map"></div>
<script>
    // var key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
    var key = 'AkqnDaYoiynQM-UCWHQrlWO5PEpGBJknYCH1Sct1ZxikHxeDjJanwQ4ZdyEhB8XU';

    var roads = new ol.layer.Tile({
        source: new ol.source.BingMaps({ key: key, imagerySet: 'Road' })
    });

    var imagery = new ol.layer.Tile({
        source: new ol.source.BingMaps({ key: key, imagerySet: 'Aerial' })
    });
    // var baselayer = new ol.layer.Tile({
    //     source: new ol.source.XYZ({
    //         url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}'
    //     })
    // });
    var container = document.getElementById('map');

    var map = new ol.Map({
        layers: [roads, imagery],
        // layers: [baselayer],
        target: container,
        view: new ol.View({
            center: ol.proj.fromLonLat([-109, 46.5]),
            zoom: 6
        })
    });

    var radius = 75;

    //改变遮罩大小的作用
    document.addEventListener('keydown', function (evt) {
        if (evt.which === 38) {
            radius = Math.min(radius + 5, 150);
            map.render();
            evt.preventDefault();
        } else if (evt.which === 40) {
            radius = Math.max(radius - 5, 25);
            map.render();
            evt.preventDefault();
        }
    });

    var mousePosition = null;

    container.addEventListener('mousemove', function (event) {
        mousePosition = map.getEventPixel(event);
        map.render();
    });
    //当鼠标移出地图可视区时，停止遮罩绘制
    container.addEventListener('mouseout', function () {
        mousePosition = null;
        map.render();
    });


    //绑定在卫星遮罩层上，在渲染之前，
    imagery.on('precompose', function (event) {
        var ctx = event.context;
        var pixelRatio = event.frameState.pixelRatio;//获取像素密度
        ctx.save(); //先保存上下文

        ctx.beginPath();
        if (mousePosition) {
            ctx.arc(mousePosition[0] * pixelRatio, mousePosition[1] * pixelRatio,
                radius * pixelRatio, 0, 2 * Math.PI);//绘制圆形的路径
            ctx.lineWidth = 5 * pixelRatio;
            ctx.strokeStyle = 'rgba(0,0,0,0.5)';
            ctx.stroke();
        }
        ctx.clip(); //在闭合圆形路径中显示卫星图层，

    });

    //绘制完成后，恢复现场； 若没有此操作，会造成遮罩层重复录制，内层溢出
    imagery.on('postcompose', function (event) {
        var ctx = event.context;
        ctx.restore();
    });


</script>
</body>

</html>